const PEDDING = "pending",
  FULFILLED = "fulfilled",
  REJECTED = "rejected";
function isPromise(val) {
  return (
    val !== undefined &&
    val !== null &&
    (typeof val === 'object' || typeof val === 'function') &&
    typeof val.then === 'function'
  );
}
/**
 * @todo  The Promise Resolution Procedure=>Promise的解决流程
 * @description Promise/A+ 规范
 *  的承诺解决过程是一个抽象的操作作为输入一个承诺和一个值，它表示我们作为[[Resolve]](promise, x)。如果x是可能的，则在行为至少类似于承诺的假设下，
 *  尝试promise采用的状态。否则，它将满足value 。xxpromisex只要对约定的实现公开Promises / A +兼容的then方法，对约定的实现就可以进行互操作。
 *  它还允许Promises / A +实现以合理的then方法“同化”不合格的实现。
    要运行[[Resolve]](promise, x)，请执行以下步骤：
    2.3.1    如果promise和x引用相同的对象，promise则以拒绝TypeError为理由。
    2.3.2    如果x是一个承诺，则采用其状态[ 3.4 ]：
      2.3.2.1      如果x未决，则promise必须保持未决状态，直到x实现或被拒绝。
      2.3.2.2      如果/何时x满足，promise则以相同的值满足。
      2.3.2.3      如果/何时x被拒绝，promise则以相同的理由拒绝。
    2.3.3    否则，如果x是对象或函数，
      2.3.3.1     我们then是x.then。[ 3.5 ]
      2.3.3.2     如果检索属性x.then中抛出的异常的结果e，拒绝promise与e作为的原因。
      2.3.3.3     如果then是函数，请使用xas this，第一个参数resolvePromise和第二个参数进行调用rejectPromise，其中：
        2.3.3.3.1      如果/何时resolvePromise使用值调用y，请运行[[Resolve]](promise, y)。
        2.3.3.3.2      如果/当rejectPromise是带一个理由r，拒绝promise与r。
        2.3.3.3.3      如果同时调用resolvePromise和rejectPromise，或者对同一参数进行了多次调用，则第一个调用优先，而所有其他调用均被忽略。
        2.3.3.3.4      如果调用then引发异常e，
        2.3.3..3.4.1       如果resolvePromise或rejectPromise已经被调用，则忽略它。
        2.3.3..3.4.2       否则，拒绝promise与e作为的原因。
      2.3.3.4          如果then不是一个函数，实现promise用x。
    2.3.4     如果x不是一个对象或功能，实现promise与x。
        如果使用参与循环的可循环链的可转换组件来解决承诺，从而[[Resolve]](promise, thenable)最终导致递归性质[[Resolve]](promise, thenable)被再次调用，
    则遵循上述算法将导致无限递归。鼓励但不是必需的实现，以检测这种递归并promise以提供信息TypeError为理由的拒绝。[ 3.6 ]
 * @param {Promise} promise2 
 * @param {*} x 
 * @param {Function} resolve 
 * @param {Function} reject 
 * @returns {void}
 */
function resolvePromise(promise2, x, resolve, reject) {
  //如果promise和x引用相同的对象，promise则以拒绝TypeError为理由。
  /**
   * 例子:
   * const p=new myPromise((resolve,reject)=>{
   *  resolve(xxx);
   * }).then(v=>{
   *  return p;
   * })
   */
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise'));
  }
  //保证promise2的onFulfilled或者onRejected只被调用一次 防止多次调用
  //比如:
  /**
   * new myPromise((resolve,reject)=>{
   *    resolve(xxx);
   *    reject(xxx);
   *    resolve(xxx);
   *  })；
   * 这样就会导致promise2的onFulfilled或者onRejected被多次调用
   */
  let called = false;
  if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
    try {
      //then be x.then=>取出then
      const then = x.then;
      // 如果then是函数，就默认是promise了
      if (typeof then === 'function') {
        then.call(x,
          //If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).=> 如果/何时resolvePromise使用值调用y，请运行[[Resolve]](promise, y)。
          (y) => {
            //只能调用一次
            if (called) return;
            called = true;
            //如果y依旧是一个promise 那么就递归解析
            /**
             * 例子:
             * new Promose((resolve,reject)=>{
             *     resolve('xxx');
             * }).then((v)=>{
             *    return new myPromise((resolve,reject)=>{
             *      setTimeout(()=>{
             *         resolve(new myPromise((resolve,reject)=>{
             *              resolve(new myPromise((resolve,reject)=>{
             *                  resolve(new myPromise(...);//嵌套地狱
             *              }))
             *          }))
             *      }13000)
             *  })
             * })
             */
            resolvePromise(promise2, y, resolve, reject);
          },
          //If/when rejectPromise is called with a reason r, reject promise with r.=>  如果/当rejectPromise是带一个理由r，拒绝promise与r。
          (r) => {
            //只能调用一次
            if (called) return;
            called = true;
            reject(r);
          });
      } else {
        resolve(x);
      }
    } catch (e) {
      //取then失败或者流程报错走到这里
      if (called) return;
      called = true;
      reject(e);
    }
  } else {
    //If x is not an object or function, fulfill promise with x.=>如果x不是一个对象或者函数 
    resolve(x);
  }
}
class myPromise {
  /**
   * @description Promise 构造器主要用于包装不支持promise（返回值不是Promise）的函数。
   * @param {*} executor 
   */
  constructor(executor) {
    if (isPromise(executor)) {
      // Promise 构造器主要用于包装不支持promise（返回值不是Promise）的函数
      throw new TypeError("Promise resolver #<Promise> is not a function");
    }
    //私有属性 这里为什么是callbacks(一个事件队列)？请看下面的例子:
    /**
     * const promise=new myPromise((resolve,reject)=>{...});
     * promise.then(...);
     * promise.then(...);
     * promise.then(...);
     * promise.then(...);
     * ...可以无穷尽也 
     * 根据promise/A+规范 所有的onFulfilled或者onRejected必须按照原调用顺序执行 所以这里才是一个队列
     */
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    this.onFinallyCallbacks = [];
    this.reason = undefined;
    this.value = undefined;
    this.state = PEDDING;
    const reject = (reason) => {
      if (this.state === PEDDING) {
        this.state = REJECTED;
        //reason=reject(xxx)中传递的xxx
        this.reason = reason;
        this.onRejectedCallbacks.forEach(callback => callback());
        this.onFinallyCallbacks.forEach(callback => callback());
      }
    }
    const resolve = (value) => {
      if (this.state === PEDDING) {
        this.state = FULFILLED;
        //value=resolve(xxx)中传递的xxx
        this.value = value;
        this.onFulfilledCallbacks.forEach(callback => callback());
        this.onFinallyCallbacks.forEach(callback => callback());
      }
    }
    try {
      executor && typeof executor === 'function' && executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }
  /**
   * @todo  //规范：
  // 当一个 Promise 完成（fulfilled）或者失败（rejected）时，返回函数将被异步调用（由当前的线程循环来调度完成）.
     具体的返回值依据以下规则返回。如果 then 中的回调函数：
  // 返回了一个值，那么 then 返回的 Promise 将会成为接受状态，并且将返回的值作为接受状态的回调函数的参数值。
  // 没有返回任何值，那么 then 返回的 Promise 将会成为接受状态，并且该接受状态的回调函数的参数值为 undefined。
  // 抛出一个错误，那么 then 返回的 Promise 将会成为拒绝状态，并且将抛出的错误作为拒绝状态的回调函数的参数值。
  // 返回一个已经是接受状态的 Promise，那么 then 返回的 Promise 也会成为接受状态，
     并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
  // 返回一个已经是拒绝状态的 Promise，那么 then 返回的 Promise 也会成为拒绝状态，
     并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
  // 返回一个未定状态（pending）的 Promise，那么 then 返回 Promise 的状态也是未定的，并且它的终态与那个 Promise 的终态相同；
     同时，它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。
   * @param {*} onFulfilled  当 Promise 变成接受状态（fulfilled）时调用的函数。该函数有一个参数，即接受的最终结果（the fulfillment  value）。
   *                         如果该参数不是函数，则会在内部被替换为 (x) => x，即原样返回 promise 最终结果的函数
   * @param {*} onRejected   当 Promise 变成拒绝状态（rejected）时调用的函数。该函数有一个参数，即拒绝的原因（rejection reason）。  
   *                         如果该参数不是函数，则会在内部被替换为一个 "Thrower" 函数 (it throws an error it received as argument)。
   * @returns {Promise}
   */
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled != 'function') {
      //如果该参数不是函数，则会在内部被替换为 (x) => x，即原样返回 promise 最终结果的函数
      onFulfilled = (x) => x;
    }
    if (typeof onRejected != 'function') {
      // 如果该参数不是函数，则会在内部被替换为一个 "Thrower" 函数 (it throws an error it received as argument)
      onRejected = (reason) => { throw reason };
    }
    //偷懒函数 少写重复代码
    const handler = (promise2, valueOrReason, onFOrR, resolve, reject) => {
      try {
        const result = onFOrR(valueOrReason);
        resolvePromise(promise2, result, resolve, reject);
      } catch (e) {
        reject(e);
      }
    }
    const promise2 = new myPromise((resolve, reject) => {
      try {
        if (this.state === PEDDING) {
          //当前Promise处于pedding状态下 则将onFulfilled和onRejected加入回调队列中 等待Promise的状态被改变时调用
          this.onFulfilledCallbacks.push(
            () => {
              //这里为什么用setTimeout? =>2.2.4: `onFulfilled` or `onRejected` must not be called until the execution context stack contains 
              //only platform code. Clean-stack execution ordering tests (fulfillment case) when the promise is fulfilled asynchronously
              //timeout of 200ms exceeded. Ensure the done() callback is being called in this test
              setTimeout(() => {
                /**
                 *  resolvePromise这个是对 最顶层的Promise嵌套问题
                 *  这里的处理promise/A+并没有规范，但是ESCMSCript6的Promise扩展了这个功能，所以把es6的扩展也实现一下
                 *  例子:
                 *  const new Promose((resolve,reject)=>{
                 *   resolve(new myPromise((resolve,reject)=>{
                 *       new myPromise(...)
                 *   }))
                 *  })
                 */
                resolvePromise(
                  promise2,
                  this.value,
                  (v) => { handler(promise2, v, onFulfilled, resolve, reject); },
                  (r) => { handler(promise2, r, onRejected, resolve, reject); }
                );
              }, 0);
              // setTimeout(() => handler(promise2, this.value, onFulfilled, resolve, reject), 0);
            }
          );
          this.onRejectedCallbacks.push(
            () => {
              setTimeout(() => handler(promise2, this.reason, onRejected, resolve, reject), 0);
            }
          );
        } else if (this.state === FULFILLED) {
          //当前Promise处于fulfilled状态下 则“直接调用” 这里通过setTimeout来执行异步任务
          setTimeout(() => {
            resolvePromise(
              promise2,
              this.value,
              (v) => { handler(promise2, v, onFulfilled, resolve, reject); },
              (r) => { handler(promise2, r, onRejected, resolve, reject); }
            );
          }, 0);
        } else if (this.state === REJECTED) {
          //当前Promise处于rejected状态下 则“直接调用” 这里通过setTimeout来执行异步任务 模拟微任务
          setTimeout(() => handler(promise2, this.reason, onRejected, resolve, reject), 0);
        }
      } catch (err) {
        //整个exctutor运行发生异常 则直接reject
        reject(err);
      }
    });
    return promise2;
  }
  /**
   * @todo 规范: catch() 方法返回一个Promise (en-US)，并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected) 相同。
   *             (事实上, calling obj.catch(onRejected)  内部calls obj.then(undefined, onRejected)).
   * 
   * @description                  catch 方法可以用于您的promise组合中的错误处理。
   * @param       {*} onRejected   当Promise 被rejected时,被调用的一个Function。 该函数拥有一个参数：reason    rejection 的原因。
   *                               如果 onRejected 抛出一个错误或返回一个本身失败的 Promise ，  通过 catch() 返回的Promise 被rejected；否则，它将显示为成功（resolved）。
   * @returns {Promise}
   */
  catch(onRejected) {
    //事实上, calling obj.catch(onRejected)  内部calls obj.then(undefined, onRejected)
    return this.then(undefined, onRejected);
  }
  /**
   * @todo 规范: finally() 方法返回一个Promise。在promise结束时，无论结果是fulfilled或者是rejected，都会执行指定的回调函数。
   *             这为在Promise是否成功完成后都需要执行的代码提供了一种方式。这避免了同样的语句需要在then()和catch()中各写一次的情况。
   * @description 如果你想在 promise 执行完毕后无论其结果怎样都做一些处理或清理时，finally() 方法可能是有用的。
                  finally() 虽然与 .then(onFinally, onFinally) 类似，它们不同的是：
                  调用内联函数时，不需要多次声明该函数或为该函数创建一个变量保存它。
                  由于无法知道promise的最终状态，所以finally的回调函数中不接收任何参数，它仅用于无论最终结果如何都要执行的情况。
                  与Promise.resolve(2).then(() => {}, () => {}) （resolved的结果为undefined）不同，Promise.resolve(2).finally(() => {}) resolved的结果为 2。
                  同样，Promise.reject(3).then(() => {}, () => {}) (resolved 的结果为undefined), Promise.reject(3).finally(() => {}) rejected 的结果为 3。
                  注意: 在finally回调中 throw（或返回被拒绝的promise）将以 throw() 指定的原因拒绝新的promise.
   * @param {*} onFinally 
   * @returns {Promise}  返回一个设置了 finally 回调函数的Promise对象。 
   */
  finally(onFinally) {
    return new myPromise((resolve, reject) => {
      if (this.state == FULFILLED) {
        setTimeout(() => {
          try {
            onFinally();
            resolve(this.value);
          } catch (err) {
            reject(err);
          }
        }, 0);
      } else if (this.state === REJECTED) {
        setTimeout(() => {
          try {
            onFinally();
            resolve(this.reason);
          } catch (err) {
            reject(err);
          }
        }, 0);
      } else if (this.state === PEDDING) {
        this.onFinallyCallbacks.push(() => {
          try {
            onFinally();
            resolve(this.state === FULFILLED ? this.value : this.reason);
          } catch (err) {
            reject(err);
          }
        });
      }
    });
  }
  /**
   * @static 静态方法
   * @description 规范： Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise,那么将返回这个 promise；
   *              如果这个值是thenable（即带有"then" 方法），返回的promise会“跟随”这个thenable的对象，采用它的最终状态；
   *              否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。
   * @warning     不要在解析为自身的thenable 上调用Promise.resolve。这将导致无限递归，因为它试图展平无限嵌套的promise。
   * @param {*} value 
   * @returns {Promise}
   */
  static resolve(value) {
    return new myPromise((resolve, reject) => {
      if (isPromise(value)) {
        value.then(resolve, reject);
      } else {
        resolve(value)
      }
    });
  }
  /**
   * @todo  Promise.reject()方法返回一个带有拒绝原因的Promise对象。
   * @static
   * @description 静态函数Promise.reject返回一个被拒绝的Promise对象。通过使用Error的实例获取错误原因reason对调试和选择性错误捕捉很有帮助。
   * @param {*} reason 
   * @returns {Promise}
   */
  static reject(reason) {
    return new myPromise((_, reject) => {
      reject(reason);
    });
  }
  /**
   * @todo 规范： Promise.all() 方法接收一个promise的iterable类型（注：Array，Map，Set都属于ES6的iterable类型）的输入，
   *       并且只返回一个Promise实例， 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在
   *       所有输入的promise的resolve回调都结束，或者输入的iterable里没有promise了的时候。它的reject回调执行是，只要任何一个输入的
   *       promise的reject回调执行或者输入不合法的promise就会立即抛出错误，并且reject的是第一个抛出的错误信息。
   * @description  Promise.allSettled()不管参数中的promise是fulfilled还是rejected，都会等参数中的实例都返回结果，包装实例才会结束。
   *               Promise.all()只有在接受的所有promise实例全部是fulfilled才会走Promise.all([p1,p2,p3]).then()方法，
   *               只要有其中一个promise实例是rejected，就会直接走catch方法，并且catch中只会返回第一个变成rejected的promise的错误
   * @param {*} iterable 
   * @returns {Promise} 规范： 如果传入的参数是一个空的可迭代对象，则返回一个已完成（already resolved）状态的 Promise。
                                如果传入的参数不包含任何 promise，则返回一个异步完成（asynchronously resolved） Promise。
                                注意：Google Chrome 58 在这种情况下返回一个已完成（already resolved）状态的 Promise。
                                其它情况下返回一个处理中（pending）的Promise。这个返回的 promise 之后会在所有的 promise 
                                都完成或有一个 promise 失败时异步地变为完成或失败。 
                                返回值将会按照参数内的 promise 顺序排列，而不是由调用 promise 的完成顺序决定。
   */
  static all(iterable) {
    return new myPromise((resolve, reject) => {
      try {
        let values = [],
          len = 0, //用来标记已迭代元素的数量 因为iterable可能是用户自定义迭代器对象（没有length或者size属性）。
          isWalkComplete = false,
          promiseList = [], //用一个数组保存住按照iterable中的排序的所有promise对象
          promise;
        const getSortPromiseValue = () => promiseList.map(p => p.value);
        for (const iter of iterable) {
          promise = !isPromise(iter) ? /***传入的参数里面不是promise,将它转变成promise***/ Promise.resolve(iter) : iter;
          promiseList.push(promise); //复制或者说保存当前顺序的promise的引用
          //执行then方法
          promise.then(
            (v) => {
              values.push(v);
              if (
                typeof iterable === 'string' ||
                Array.isArray(iterable) ||
                iterable instanceof Map ||
                iterable instanceof Set
              ) {
                if (values.length === (iterable.length || iterable.size)) {
                  //处理返回值的顺序
                  values = getSortPromiseValue();
                  resolve(values);
                }
              } else if (isWalkComplete && values.length === len) {
                //处理返回值的顺序
                values = getSortPromiseValue();
                resolve(values)
              }
            },
            reason => reject(reason) //传入第一个发生reject的reason
          ); //then end
          len++;
        } //end for
        isWalkComplete = true;
      } catch (err) {
        reject(err);
      }
    });
  }
  /**
   * @todo 该Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise，
   *       并带有一个对象数组，每个对象表示对应的promise结果。
           当您有多个彼此不依赖的异步任务成功完成时，或者您总是想知道每个promise的结果时，通常使用它。
           相比之下，Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束
   * @param {*} iterable 一个可迭代的对象，例如Array，其中每个成员都是Promise。
   * @returns {Promise}  一旦所指定的 promises 集合中每一个 promise 已经完成，无论是成功的达成或被拒绝，未决议的 Promise将被异步完成。
   *                     那时，所返回的 promise 的处理器将传入一个数组作为输入，该数组包含原始 promises 集中每个 promise 的结果。
                         对于每个结果对象，都有一个 status 字符串。如果它的值为 fulfilled，则结果对象上存在一个 value 。如果值为 rejected，
                         则存在一个 reason 。value（或 reason ）反映了每个 promise 决议（或拒绝）的值。
   */
  static allSettled(iterable) {
    return new myPromise((resolve, reject) => {
      //已经完成了的Promose 不管是状态是fulfilled还是rejected
      let completePromiseList = [],
        promiseList = [],
        len = 0,
        completePromiseCount = 0,
        isWalkComplete = false;
      const getSortPromiseStatus = () => {
        return promiseList.map(p => {
          return {
            status: p.state,
            [p.state === FULFILLED ? 'value' : 'reason']: p.state === FULFILLED ? p.value : p.reason
          }
        });
      };
      for (const x of iterable) {
        let promise = !isPromise(x) ? Promise.resolve(x) : x;
        promiseList.push(promise);
        promise.finally(() => {
          completePromiseCount++;
          if (isWalkComplete && completePromiseCount === len) {
            completePromiseList = getSortPromiseStatus();
            resolve(completePromiseList);
          }
        });
        len++;
      }
      isWalkComplete = true;
    });
  }
  /**
   * @todo Promise.race(iterable) 方法返回一个 promise，一旦迭代器中的某个promise解决或拒绝，返回的 promise就会解决或拒绝。
   * @description race 函数返回一个 Promise，它将与第一个传递的 promise 相同的完成方式被完成。
   *              它可以是完成（ resolves），也可以是失败（rejects），这要取决于第一个完成的方式是两个中的哪个。
                  如果传的迭代是空的，则返回的 promise 将永远等待。
                  如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺，则 Promise.race 将解析为迭代中找到的第一个值。
   * @param {*} iterable 可迭代对象，类似Array。详见 iterable。
   * @returns {Promise} 一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝，就采用第一个promise的值作为它的值，
   *                    从而异步地解析或拒绝（一旦堆栈为空）。
   */
  static race(iterable) {
    return new myPromise((resolve, reject) => {
      for (const iter of iterable) {
        //如果迭代包含一个或多个非承诺值和/或已解决/拒绝的承诺，则 Promise.race 将解析为迭代中找到的第一个值。
        if (isPromise(iter)) {
          //如果iter是个promise
          const promise = iter;
          //判断promise的状态来动态选择接受或者拒绝
          if (promise.state === FULFILLED) {
            promise.then(resolve);
          } else if (promise.state === REJECTED) {
            promise.then(undefined, reject);
          } else if (promise.state === PEDDING) {
            promise.then(resolve, reject);
          }
        } else {
          //非promise类型直接resolve
          resolve(iter)
        }
      }
    });
  }
  /**
   * @todo ECMAScript6的文档规范: Promise.any() 接收一个Promise可迭代对象，只要其中的一个 promise 成功，就返回那个已经成功的 promise 。
   *       如果可迭代对象中没有一个 promise 成功（即所有的 promises 都失败/拒绝），就返回一个失败的 promise 和AggregateError类型的实例，
   *       它是 Error 的一个子类，用于把单一的错误集合在一起。本质上，这个方法和Promise.all()是相反的。
   * @description 这个方法用于返回第一个成功的 promise 。只要有一个 promise 成功此方法就会终止，它不会等待其他的 promise 全部完成。
                  不像 Promise.all() 会返回一组完成值那样（resolved values），我们只能得到一个成功值（假设至少有一个 promise 完成）。
                  当我们只需要一个 promise 成功，而不关心是哪一个成功时此方法很有用的。
                  同时, 也不像 Promise.race() 总是返回第一个结果值（resolved/reject）那样，这个方法返回的是第一个 成功的 值。
                  这个方法将会忽略掉所有被拒绝的 promise，直到第一个 promise 成功。
   * @warning Promise.any() 方法依然是实验性的，尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案（Stage 4）
   * @param {*} iterable  一个可迭代的对象, 例如 Array、Set、Map、String
   * @returns {Promise}  如果传入的参数是一个空的可迭代对象，则返回一个 已失败（already rejected） 状态的 Promise。
                         如果传入的参数不包含任何 promise，则返回一个 异步完成 （asynchronously resolved）的 Promise。
                         其他情况下都会返回一个处理中（pending） 的 Promise。 只要传入的迭代对象中的任何一个 promise 变成成功（resolve）
                         状态，或者其中的所有的 promises 都失败，那么返回的 promise 就会 异步地（当调用栈为空时） 
                         变成成功/失败（resolved/reject）状态。
   */
  static any(iterable) {
    return new myPromise((resolve, reject) => {
      let len = 0, //记录迭代器中元素的数量
        isWalkComplete = false, //标识迭代器遍历完成
        promiseList = [], //用一个数组保存住按照iterable中的排序的所有promise对象
        errors = []; //记录所有的错误
      const getSortPromiseReason = () => promiseList.map(p => p.reason);
      for (const iter of iterable) {
        if (isPromise(iter)) {
          const promise = iter;
          promiseList.push(promise);
          promise.then(
            v => {
              resolve(v);
              return;
            },
            reason => {
              errors.push(reason);
              //迭代器遍历完成 但是所有的promise值都失败了
              if (isWalkComplete && errors.length === len) {
                //获取排序后的promise的reason
                errors = getSortPromiseReason();
                reject(new AggregateError(errors, 'All promises were rejected'));
              }
            }
          );
        } else {
          resolve(iter);
        }
        len++;
      }
      isWalkComplete = true;
      //判断迭代器是否为空
      if (len === 0) {
        reject(new AggregateError(errors, 'All promises were rejected'));
      }
    });
  }
}

// Promise.deferred = function() {
//   const deferred = {}
//   deferred.promise = new myPromise((resolve, reject) => {
//       deferred.resolve = resolve
//       deferred.reject = reject
//   })
//   return deferred
// }
// module.exports = Promise;

// 版权声明：本文为CSDN博主「稀饭joker」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
// 原文链接：https://blog.csdn.net/weixin_44337922/article/details/115803322